package com.foryou.swkj.core.util;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 日期工具类，提供有关日期操作方面的方法。
 */

public class DateUtil {

    public final static String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

   /**
    * 时间格式
    */
   public final static String TIME_FORMAT = "HH:mm:ss:SS";

   /**
    * 缺省短日期格式
    */
   public final static String DEFAULT_SHORT_DATE_FORMAT = "yyyy-MM-dd";

   /**
    * 缺省短日期格式
    */
   public final static String DEFAULT_SHORT_DATE_FORMAT_ZH = "yyyy年M月d日";

   /**
    * 缺省长日期格式
    */
   public final static String DEFAULT_LONG_DATE_FORMAT =
      DEFAULT_SHORT_DATE_FORMAT + " " + TIME_FORMAT;

   /**
    * Java能支持的最小日期字符串（yyyy-MM-dd）。
    */
   public final static String JAVA_MIN_SHORT_DATE_STR = "1970-01-01";

   /**
    * Java能支持的最小日期字符串（yyyy-MM-dd HH:mm:ss:SS）。
    */
   public final static String JAVA_MIN_LONG_DATE_STR = "1970-01-01 00:00:00:00";

    /**
     * 无分割符格式
     */
   public final static String WITHOUT_DELIMETER_DATE_FORMAT = "yyyyMMdd";

   /**
    * Java能支持的最小的Timestamp。
    */
   public final static Timestamp JAVA_MIN_TIMESTAMP = convertStrToTimestamp(
      JAVA_MIN_LONG_DATE_STR);

   /**
    * 上周的周末
    * @return
    */
   public static Date getLastSunday(){
       Calendar now = Calendar.getInstance();
       Calendar lastSunday = (Calendar) now.clone();
       lastSunday.add(Calendar.DAY_OF_MONTH, -(now.get(Calendar.DAY_OF_WEEK) - 1));
       lastSunday.set(Calendar.HOUR_OF_DAY, 23);
       lastSunday.set(Calendar.MINUTE, 59);
       lastSunday.set(Calendar.SECOND, 59);
       return lastSunday.getTime();
   }
   /**
    * 获取下周时间
    * @return
    */
   public static Date getWeek(){
	   Calendar curr = Calendar.getInstance();
	   curr.set(Calendar.DAY_OF_MONTH,curr.get(Calendar.DAY_OF_MONTH)+7);
	   return curr.getTime();
   }
   /**
    * 获取下个月时间
    * @return
    */
   public static Date getMonth(){
		Date dNow = new Date(); // 当前时间
		Date dBefore = new Date();
		Calendar calendar = Calendar.getInstance(); // 得到日历
		calendar.setTime(dNow);// 把当前时间赋给日历
		calendar.add(Calendar.MONTH,1);
		dBefore = calendar.getTime(); 
	   
//	   Calendar curr = Calendar.getInstance();
//	   curr.set(Calendar.DAY_OF_MONTH,curr.get(Calendar.DAY_OF_MONTH)+7);
	   return dBefore;
   }
   /**
	 * 返回适用的dayOfWeek，1-7
	 * @param date yyyy-MM-dd
	 * @return
	 */
	public static int getDayOfWeek(String date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(DateUtil.convertStrToDate(date, "yyyy-MM-dd"));
		int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if(dayOfWeek == 0){
			dayOfWeek = 7;
		}
		return dayOfWeek;
	}
   
   /**
    * 上周周一
    * @return
    */
   public static Date getLastMonday(){
	   Calendar now = Calendar.getInstance();
       Calendar lastMonday = (Calendar) now.clone();
       lastMonday.add(Calendar.DAY_OF_MONTH, -(now.get(Calendar.DAY_OF_WEEK) - 1) - 6);
       lastMonday.set(Calendar.HOUR_OF_DAY, 0);
       lastMonday.set(Calendar.MINUTE, 0);
       lastMonday.set(Calendar.SECOND, 0);
       return lastMonday.getTime();
   }
   
   /**
    * 把字符串转换为Timestamp类型，对于短日期格式，自动把时间设为系统当前时间。
    * @return Timestamp
    * @see #convertStrToTimestamp(String,boolean)
    */
   public static Timestamp convertStrToTimestamp(String dateStr) {
      return convertStrToTimestamp(dateStr, false);
   }

   /**
    * 把字符串转换为Timestamp类型，对于短日期格式，自动时间设为0。
    * @return Timestamp
    * @see #convertStrToTimestamp(String,boolean)
    */
   public static Timestamp convertStrToTimestampZero(String dateStr) {
      return convertStrToTimestamp(dateStr, true);
   }

   public static String nDayAfter(){
	        Calendar cal = Calendar.getInstance();
	        cal.setTime(new Date());
	        cal .set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),cal.get(Calendar.DAY_OF_MONTH)+2, 23,59, 59);
	        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
	       String mydate= simpleDateFormat.format(cal.getTime());
	        return mydate;   

   }
   public static String tomorrowDayAfter(){
       Calendar cal = Calendar.getInstance();
       cal.setTime(new Date());
       cal .set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),cal.get(Calendar.DAY_OF_MONTH)+1, 23,59, 59);
       SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
      String mydate= simpleDateFormat.format(cal.getTime());
       return mydate;   

}
    /**
     * date的下一天
	 * @param date
	 * @return yyyy-MM-dd
	 */
   public static String nextDayStr(Date date){
	   Calendar cal = Calendar.getInstance();
	   cal.setTime(date);
	   cal.add(Calendar.DAY_OF_MONTH, 1);
	   return convertDateToStr(cal.getTime(), "yyyy-MM-dd");
   }
   public static String dafTomorrowDayAfter(){
       Calendar cal = Calendar.getInstance();
       cal.setTime(new Date());
       cal .set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),cal.get(Calendar.DAY_OF_MONTH)+3, 23,59, 59);
       SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
      String mydate= simpleDateFormat.format(cal.getTime());
       return mydate;   

}
   
   public static String currentDate(){
	return    getCurrDateStr("yyyyMMdd");
   }
   /**
    * 把字符串转换为Timestamp类型。
    * @param dateStr - 日期字符串，只支持"yyyy-MM-dd"和"yyyy-MM-dd HH:mm:ss:SS"两种格式。
    * 如果为"yyyy-MM-dd"，系统会自动取得当前时间补上。
    * @param addZeroTime - 当日期字符串为"yyyy-MM-dd"这样的格式时，addZeroTime为true表示
    * 用0来设置HH:mm:ss:SS，否则用当前Time来设置。
    * @return Timestamp
    */
   private static Timestamp convertStrToTimestamp(String dateStr,
                                                  boolean addZeroTime) {
      if (dateStr == null) {
         return null;
      }

      String dStr = dateStr.trim();
      if (dStr.indexOf(" ") == -1) {
         if (addZeroTime) {
            dStr = dStr + " 00:00:00:00";
         }
         else {
            dStr = dStr + " " + getCurrDateStr(DateUtil.TIME_FORMAT);
         }
      }

      Date utilDate = null;
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
         DEFAULT_LONG_DATE_FORMAT);

      try {
         utilDate = simpleDateFormat.parse(dStr);
      }
      catch (Exception ex) {
         throw new RuntimeException("DateUtil.convertStrToTimestamp(): "
                                    + ex.getMessage());
      }

      return new Timestamp(utilDate.getTime());
   }

   /**
    * 得到系统当前时间的Timestamp对象
    * @return  系统当前时间的Timestamp对象
    */
   public static Timestamp getCurrTimestamp() {
      return new Timestamp(System.currentTimeMillis());
   }

   /**
    * <p>
    * 取得当前日期，并将其转换成格式为"dateFormat"的字符串
    * 例子：假如当前日期是 2003-09-24 9:19:10，则：
    * <pre>
    * getCurrDateStr("yyyyMMdd")="20030924"
    * getCurrDateStr("yyyy-MM-dd")="2003-09-24"
    * getCurrDateStr("yyyy-MM-dd HH:mm:ss")="2003-09-24 09:19:10"
    * </pre>
    * </p>
    * @param dateFormat String 日期格式字符串
    * @return String
    */
   public static String getCurrDateStr(String dateFormat) {
      return convertDateToStr(new Date(), dateFormat);
   }

   /**
    * 将日期类型转换成指定格式的日期字符串
    * @param date 待转换的日期
    * @param dateFormat 日期格式字符串
    * @return String
    */
   public static String convertDateToStr(Date date, String dateFormat) {
      if (date == null) {
         return "";
      }
      SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
      return sdf.format(date);
   }

   /**
    * 将指定格式的字符串转换成星期
    * @param dateFormat 待转换的日期字符串的日期格式字符串
    * @return Date
    */
   public static String convertStrToWeek(String dateStr, String dateFormat) {
      if (dateStr == null || dateStr.equals("")) {
         return null;
      }
      return convertDateToStr(convertStrToDate(dateStr,dateFormat),"E");
   }

   /**
    * 将指定格式的字符串转换成日期类型
    * @param dateFormat 日期格式字符串
    * @return Date
    */
   public static Date convertStrToDate(String dateStr, String dateFormat) {
      if (dateStr == null || dateStr.equals("")) {
         return null;
      }
      SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
      try {
         return sdf.parse(dateStr);
      }
      catch (Exception e) {
         throw new RuntimeException("DateUtil.convertStrToDate():" +
                                    e.getMessage());
      }
   }
    
    public static java.sql.Date convertStrToSqlDate(String s) {
        return convertToSqlDate(convertStrToDate(s , DEFAULT_SHORT_DATE_FORMAT));
    }

   /**
    * 把java.util.Date转换为java.sql.Date。
    * @param date
    * @return
    */
   public static java.sql.Date convertToSqlDate(Date date) {
      if (date == null) {
         return null;
      }

      String dateStr = convertDateToStr(date, DEFAULT_SHORT_DATE_FORMAT);
      return java.sql.Date.valueOf(dateStr);
   }
    
    public static java.sql.Date convertToSqlDate() {
        Date date = new Date();
        String dateStr = convertDateToStr(date, DEFAULT_SHORT_DATE_FORMAT);
        return java.sql.Date.valueOf(dateStr);    
    }

   /**
    * 计算两个日期之间的相隔的年、月、日。注意：只有计算相隔天数是准确的，相隔年和月都是
    * 近似值，按一年365天，一月30天计算，忽略闰年和闰月的差别。
    * @param datepart 两位的格式字符串，yy表示年，MM表示月，dd表示日
    * @param startdate 开始日期
    * @param enddate 结束日期
    * @return double 如果enddate>startdate，返回一个大于0的实数，否则返回一个小于等于0的实数
    */
   public static double dateDiff(String datepart, Date startdate, Date enddate) {
      if (datepart == null || datepart.equals("")) {
         throw new IllegalArgumentException("DateUtil.dateDiff()方法非法参数值：" +
                                            datepart);
      }

      double distance = (enddate.getTime() - startdate.getTime()) /
         (60 * 60 * 24 * 1000);
      Calendar cal = Calendar.getInstance();
      cal.setTimeInMillis(enddate.getTime() - startdate.getTime());
      if (datepart.equals("yy")) {
         distance = distance / 365;
      }
      else if (datepart.equals("MM")) {
         distance = distance / 30;
      }
      else if (datepart.equals("dd")) {
         distance = (enddate.getTime() - startdate.getTime()) /
            (60 * 60 * 24 * 1000);
      }
      else if (datepart.equals("ss")){     //得到秒
        distance = (enddate.getTime() - startdate.getTime()) /(1000);
      }
      else if (datepart.equals("mm")){
        distance = (enddate.getTime() - startdate.getTime()) /(1000)/60.0;
      }
      else {
         throw new IllegalArgumentException("DateUtil.dateDiff()方法非法参数值：" +
                                            datepart);
      }
      return distance;
   }

    public static double dateDiff(String datepart, Timestamp startdate, Timestamp enddate) {
        if (datepart == null || datepart.equals("")) {
            throw new IllegalArgumentException("DateUtil.dateDiff()方法非法参数值：" +
                    datepart);
        }

        double distance = (enddate.getTime() - startdate.getTime()) /
                (60 * 60 * 24 * 1000);
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(enddate.getTime() - startdate.getTime());
        if (datepart.equals("yy")) {
            distance = distance / 365;
        }
        else if (datepart.equals("MM")) {
            distance = distance / 30;
        }
        else if (datepart.equals("dd")) {
            distance = (enddate.getTime() - startdate.getTime()) /
                    (60 * 60 * 24 * 1000);
        }
        else if("hh".equals(datepart)){
            distance = (enddate.getTime() - startdate.getTime())  * 1.0 / (1000 * 60 * 60);
        }
        else if (datepart.equals("ss")){     //得到秒
            distance = (enddate.getTime() - startdate.getTime()) /(1000);
        }
        else if (datepart.equals("mm")){
            distance = (enddate.getTime() - startdate.getTime()) /(1000)/60.0;
        }
        else {
            throw new IllegalArgumentException("DateUtil.dateDiff()方法非法参数值：" +
                    datepart);
        }
        return distance;
    }

    public static int getCurrentWeekOfYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        //取当前日期的年份里面的周数
        int currentWeekOfYear = cal.get(Calendar.WEEK_OF_YEAR);
        return currentWeekOfYear;
    }

   /**
    * 把日期对象加减年、月、日后得到新的日期对象
    * @param number 加减因子
    * @param date 需要加减年、月、日的日期对象
    * @return Date 新的日期对象
    */
   public static Date addDate(String datepart, int number, Date date) {
      Calendar cal = Calendar.getInstance();
      cal.setTime(date);
      if (datepart.equals("yy")) {
         cal.add(Calendar.YEAR, number);
      }
      else if (datepart.equals("MM")) {
         cal.add(Calendar.MONTH, number);
      }
      else if (datepart.equals("dd")) {
         cal.add(Calendar.DATE, number);
      }
      else {
         throw new IllegalArgumentException("DateUtil.addDate()方法非法参数值：" +
                                            datepart);
      }

      return cal.getTime();
   }
   
   /**
    * 
    * @param startTime 开始时间
    * @param endTime   结束时间
    * @return
    * @description 开始时间与结束时间之间的跨度是否大于12个月
    * @version 1.0 
    * @author joye
    * @update Dec 5, 2012 5:32:42 PM
    */
   public static boolean isBefore(String startTime, String endTime){
	   
	   Date sDate = DateUtil.convertStrToDate(startTime,
				DateUtil.DEFAULT_SHORT_DATE_FORMAT);
		Date eDate = DateUtil.convertStrToDate(endTime,
				DateUtil.DEFAULT_SHORT_DATE_FORMAT);
		Calendar startca = Calendar.getInstance();
		Calendar endca = Calendar.getInstance();
		startca.setTime(sDate); 
		endca.setTime(eDate);
		startca.add(startca.MONTH, 12);  //开始时间与结束时间跨度最大为12个月 
		if (startca.before(endca)){
			return true;
		}else{
			return false;
		}
	   
   }
   
   /**
    * 内部的日期格式化器
    * 用于以下的便利函数
    */
   private static final SimpleDateFormat sdf;
   private static final SimpleDateFormat sdfShort;
   private static final SimpleDateFormat sdfmd;
   static{
	   sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	   sdfShort = new SimpleDateFormat("yyyy-MM-dd");
	   sdfmd = new SimpleDateFormat("MM-dd");
   }
   
   /**
    * 以 yyyy-MM-dd HH:mm:ss 返回当前的时间
    * @author linwei
    * @return
 	*/
   public static String now(){
	   return forFull(new Date());
   }
   
   /**
    * 以 yyyy-MM-dd返回当前的时间
    * @author linwei
    * @created 2013-12-5
    * @return
    */
   public static String nowShort(){
	   return forShort(new Date());
   }
   
   /**
    * 以  yyyy-MM-dd 返回格式化的时间
    * @author linwei
    * @created 2013-12-5
    * @param date	需要格式化的时间
    * @return
    */
   public static String forShort(Date date){
	   try {
		synchronized (sdfShort) {
			   return sdfShort.format(date);
		   }
	} catch (Exception e) {
		return "";
	}
   }
   
   /**
    * 以  MM-dd 返回格式化的时间
    * @author linwei
    * @created 2013-12-6
    * @param date	需要格式化的时间
    * @return
    */
   public static String formd(Date date){
	   try {
		   synchronized (sdfmd) {
			   return sdfmd.format(date);
		   }
	   } catch (Exception e) {
		   return "";
	   }
   }
   
   /**
    * 以  yyyy-MM-dd HH:mm:ss 返回格式化的时间
    * @author linwei
    * @created 2013-12-11
    * @param date	需要格式化的时间
    * @return
    */
   public static String forFull(Date date){
	   try {
		   synchronized (sdf) {
			   return sdf.format(date);
		   }
	   } catch (Exception e) {
		   return "";
	   }
   }
   
   /** 
    * 判断时间是否在时间段内 
    *  
    * @param date 
    *            当前时间 yyyy-MM-dd HH:mm:ss 
    * @param strDateBegin 
    *            开始时间 00:00:00 
    * @param strDateEnd 
    *            结束时间 00:05:00 
    * @return 
    */  
   public static boolean isInDate(Date date, String strDateBegin,
                                  String strDateEnd) {
       SimpleDateFormat sdf = new SimpleDateFormat(" yyyy-MM-dd HH:mm:ss");
       String strDate = sdf.format(date);
       // 截取当前时间时分秒  
       int strDateH = Integer.parseInt(strDate.substring(11, 13));
       int strDateM = Integer.parseInt(strDate.substring(14, 16));
       int strDateS = Integer.parseInt(strDate.substring(17, 19));
       // 截取开始时间时分秒  
       int strDateBeginH = Integer.parseInt(strDateBegin.substring(0, 2));
       int strDateBeginM = Integer.parseInt(strDateBegin.substring(3, 5));
       int strDateBeginS = Integer.parseInt(strDateBegin.substring(6, 8));
       // 截取结束时间时分秒  
       int strDateEndH = Integer.parseInt(strDateEnd.substring(0, 2));
       int strDateEndM = Integer.parseInt(strDateEnd.substring(3, 5));
       int strDateEndS = Integer.parseInt(strDateEnd.substring(6, 8));
       if ((strDateH >= strDateBeginH && strDateH <= strDateEndH)) {  
           // 当前时间小时数在开始时间和结束时间小时数之间  
           if (strDateH > strDateBeginH && strDateH < strDateEndH) {  
               return true;  
               // 当前时间小时数等于开始时间小时数，分钟数在开始和结束之间  
           } else if (strDateH == strDateBeginH && strDateM >= strDateBeginM  
                   && strDateM <= strDateEndM) {  
               return true;  
               // 当前时间小时数等于开始时间小时数，分钟数等于开始时间分钟数，秒数在开始和结束之间  
           } else if (strDateH == strDateBeginH && strDateM == strDateBeginM  
                   && strDateS >= strDateBeginS && strDateS <= strDateEndS) {  
               return true;  
           }  
           // 当前时间小时数大等于开始时间小时数，等于结束时间小时数，分钟数小等于结束时间分钟数  
           else if (strDateH >= strDateBeginH && strDateH == strDateEndH  
                   && strDateM <= strDateEndM) {  
               return true;  
               // 当前时间小时数大等于开始时间小时数，等于结束时间小时数，分钟数等于结束时间分钟数，秒数小等于结束时间秒数  
           } else if (strDateH >= strDateBeginH && strDateH == strDateEndH  
                   && strDateM == strDateEndM && strDateS <= strDateEndS) {  
               return true;  
           } else {  
               return false;  
           }  
       } else {  
           return false;  
       }  
   }  
   
   
   /** 
    * 比较两个日期之间的大小 
    *  
    * @param d1 
    * @param d2 
    * @return 前者大于后者返回true 反之false 
    */  
   public static boolean compareDate(Date d1, Date d2) {
       Calendar c1 = Calendar.getInstance();
       Calendar c2 = Calendar.getInstance();
       c1.setTime(d1);  
       c2.setTime(d2);  
     
       int result = c1.compareTo(c2);  
       if (result >= 0)  
           return true;  
       else  
           return false;  
   }

    public static Date getDateOffset(Date date, int type, int how) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(type, how);
        return calendar.getTime();
    }

   /**
    * 测试
    * @param args
    */
   public static void main(String args[]) {
      // System.out.println(convertDateToStr(getLastMonday(), "yyyy-MM-dd HH:mm:ss"));
      // System.out.println(convertDateToStr(getLastSunday(), "yyyy-MM-dd HH:mm:ss"));
       System.out.println(convertDateToStr(getMonth(), "yyyy-MM-dd HH:mm:ss"));
      
       
   }

}
